package com.furnitur.modules.portal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.furnitur.common.exception.BusinessException;
import com.furnitur.common.utils.SecurityUtils;
import com.furnitur.core.entity.review.Review;
import com.furnitur.core.entity.review.ReviewLike;
import com.furnitur.core.mapper.review.ReviewLikeMapper;
import com.furnitur.core.mapper.review.ReviewMapper;
import com.furnitur.modules.portal.dto.review.ReviewQueryDTO;
import com.furnitur.modules.portal.dto.review.ReviewSubmitDTO;
import com.furnitur.modules.portal.service.PortalReviewService;
import com.furnitur.modules.portal.vo.review.ReviewStatsVO;
import com.furnitur.modules.portal.vo.review.ReviewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class PortalReviewServiceImpl implements PortalReviewService {

    @Autowired
    private ReviewMapper reviewMapper;
    
    @Autowired
    private ReviewLikeMapper reviewLikeMapper;

    @Override
    public Page<ReviewVO> getReviewPage(ReviewQueryDTO queryDTO) {
        Page<ReviewVO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        Long userId = SecurityUtils.getCurrentUserId();
        return reviewMapper.selectReviewPage(page, queryDTO.getFurnitureId(), 
            queryDTO.getFilterType(), queryDTO.getSortType(), userId);
    }

    @Override
    public ReviewStatsVO getReviewStats(Long furnitureId) {
        List<Map<String, Object>> statsData = reviewMapper.selectReviewStats(furnitureId);
        
        ReviewStatsVO stats = new ReviewStatsVO();
        if (statsData.isEmpty()) {
            stats.setAverageRating(0.0);
            stats.setTotal(0);
            stats.setGoodCount(0);
            stats.setMediumCount(0);
            stats.setBadCount(0);
            stats.setDistribution(new ArrayList<>());
            return stats;
        }
        
        // 计算总评价数和平均分
        int total = 0;
        double sumRating = 0;
        int goodCount = 0;
        int mediumCount = 0;
        int badCount = 0;
        
        List<ReviewStatsVO.RatingDistribution> distribution = new ArrayList<>();
        for (Map<String, Object> data : statsData) {
            int rating = ((Number) data.get("rating")).intValue();
            int count = ((Number) data.get("count")).intValue();
            total += count;
            sumRating += rating * count;
            
            // 统计各评分数量
            if (rating >= 4) {
                goodCount += count;
            } else if (rating == 3) {
                mediumCount += count;
            } else {
                badCount += count;
            }
            
            // 添加分布数据
            ReviewStatsVO.RatingDistribution item = new ReviewStatsVO.RatingDistribution();
            item.setStars(rating);
            item.setCount(count);
            distribution.add(item);
        }
        
        // 设置统计结果
        stats.setTotal(total);
        stats.setAverageRating(total > 0 ? sumRating / total : 0);
        stats.setGoodCount(goodCount);
        stats.setMediumCount(mediumCount);
        stats.setBadCount(badCount);
        
        // 计算百分比
        for (ReviewStatsVO.RatingDistribution item : distribution) {
            item.setPercentage(total > 0 ? item.getCount() * 100.0 / total : 0);
        }
        stats.setDistribution(distribution);
        
        return stats;
    }

    @Override
    @Transactional
    public void submitReview(ReviewSubmitDTO submitDTO) {
        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查是否已评价
        Long count = reviewMapper.selectCount(new LambdaQueryWrapper<Review>()
            .eq(Review::getFurnitureId, submitDTO.getFurnitureId())
            .eq(Review::getUserId, userId));
        
        if (count > 0) {
            throw new BusinessException("您已经评价过该商品了");
        }
        
        Review review = new Review();
        BeanUtils.copyProperties(submitDTO, review);
        review.setUserId(userId);
        review.setLikes(0);
        review.setCreatedAt(LocalDateTime.now());
        review.setUpdatedAt(LocalDateTime.now());
        
        try {
            reviewMapper.insert(review);
            log.info("User {} submitted review for furniture {}", userId, submitDTO.getFurnitureId());
        } catch (Exception e) {
            log.error("Failed to submit review", e);
            throw new BusinessException("评价提交失败");
        }
    }

    @Override
    @Transactional
    public void toggleReviewLike(Long reviewId) {
        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查评价是否存在
        ReviewVO review = reviewMapper.selectReviewById(reviewId, userId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        // 处理点赞/取消点赞
        ReviewLike like = reviewLikeMapper.selectByReviewAndUser(reviewId, userId);
        if (like == null) {
            // 添加点赞
            like = new ReviewLike();
            like.setReviewId(reviewId);
            like.setUserId(userId);
            reviewLikeMapper.insert(like);
            
            // 更新点赞数
            reviewMapper.incrementLikes(reviewId);
        } else {
            // 取消点赞
            reviewLikeMapper.deleteById(like.getId());
            
            // 更新点赞数
            reviewMapper.decrementLikes(reviewId);
        }
    }
}